import yaml
from pathlib import Path
from addict import Dict


class Singleton(type):
    _instances = {}

    def __call__(cls, *args, **kwargs):
        if cls not in cls._instances:
            cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
        return cls._instances[cls]


class Config(Dict, metaclass=Singleton):
    '''
    配置类，单例。继承自Dict，以便于使用。
    '''
    def __init__(self, config_path:Path = None):
        '''
        给定配置文件路径，生成配置实例。

        :param Path config_path: yaml文件路径。
        '''
        super().__init__()
        self.__default_path = Path(__file__).parent
        if not config_path:
            config_path = self.__default_path / 'config.yaml'

        self._load_config(config_path)

    def append(self, config_path:Path):
        '''
        追加配置内容，例如可通过独立文件增配模型训练参数。

        Note: 若追加配置中的某些key与已有配置key名称相同将覆盖原有配置的key内容。

        :param Path config_path: yaml文件路径。
        '''
        self._load_config(config_path)

    def _load_config(self, config: Path):
        with open(config) as f:
            settings = Dict(yaml.load(f, Loader=yaml.FullLoader))
        self.update(settings)

    @property
    def default_path(self):
        return self.__default_path


config = Config()


